//
//  DoubanLoginAppDelegate.m
//  CocoaBean
//
//  Created by sleeper on 5/26/10.
//  Copyright __MyCompany__ 2010. All rights reserved.
//

#import "GDataOAuthAuthentication.h"
#import "GDataOAuthViewControllerTouch.h"

#import "AKRequestHeader.h"
#import "NSDictionary_DoubanAddition.h"

#import "AKMiniblogViewController.h"
#import "AKMediaViewController.h"
#import "AKAppController.h"

@interface AKAppController () <AKRequestDelegate>
@end

@implementation AKAppController

@synthesize window;
@synthesize tabBarController;
@synthesize requestManager = _requestManager;
@synthesize userId = _userId;

+ (AKAppController *)sharedAppController
{
	return (AKAppController *)[UIApplication sharedApplication].delegate;
}

+ (NSString *)documentFolderPath
{
	return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

- (void)_assembleRequestManagerWithAuthentication:(GDataOAuthAuthentication *)auth
{
	AK_RELEASE(_requestManager);
	_requestManager = [[AKRequestManager alloc] initWithAuthentication:auth];
}

- (void)_obtainUserId
{
	AKRequest *request = [AKRequest new];
	request.url = [NSURL URLWithString:@"http://api.douban.com/people/%40me"];
	[_requestManager runRequest:request delegate:self];
	AK_RELEASE(request);
}

#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
    // Add the navigation controller's view to the window and display.
	miniblogViewController = [[AKMiniblogViewController alloc] init];
	mediaViewController = [[AKMediaViewController alloc] init];
	tabBarController.viewControllers = [NSArray arrayWithObjects:
										AKNavigationControllerWithRootViewController(miniblogViewController),
										AKNavigationControllerWithRootViewController(mediaViewController), nil];
	
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];
	
	GDataOAuthAuthentication *auth = [[[GDataOAuthAuthentication alloc] initWithSignatureMethod:@"HMAC-SHA1"
																					consumerKey:kAKAPIKey
																					 privateKey:kAKSecret] autorelease];
	
	if (![GDataOAuthViewControllerTouch authorizeFromKeychainForName:kAKAppName
													  authentication:auth]) {
		auth.callback = kAKCallbackName;
		[auth setRealm:@""];	// @sleeper douban doesn't ignore realm as it should.
		
		GDataOAuthViewControllerTouch *viewController = 
		[[[GDataOAuthViewControllerTouch alloc] initWithScope:nil
													 language:nil
											  requestTokenURL:[NSURL URLWithString:@"http://www.douban.com/service/auth/request_token"]
											authorizeTokenURL:[NSURL URLWithString:@"http://www.douban.com/service/auth/authorize"]
											   accessTokenURL:[NSURL URLWithString:@"http://www.douban.com/service/auth/access_token"]
											   authentication:auth
											   appServiceName:kAKAppName
													 delegate:self
											 finishedSelector:@selector(viewController:finishedWithAuth:error:)] autorelease];
		
		[viewController setDisplayName:nil]; // @sleeper douban API spec doesn't say it supports display name.
		
		[tabBarController presentModalViewController:[[[UINavigationController alloc] initWithRootViewController:viewController] autorelease] animated:YES];
	}
	else {
		[self _assembleRequestManagerWithAuthentication:auth];
		NSString *userId = [[GDataOAuthKeychain defaultKeychain] passwordForService:kAKAppName account:kAKUserIdKeychainKey error:NULL];
		if ([userId length] > 0) {
			_userId = [userId copy];
			[miniblogViewController reload];
		}
		else {
			[self _obtainUserId];
		}
	}

    return YES;
}

- (void)applicationWillTerminate:(UIApplication *)application
{
	[miniblogViewController archiveMiniblogs];
}

- (void)viewController:(GDataOAuthViewControllerTouch *)viewController
	  finishedWithAuth:(GDataOAuthAuthentication *)auth
				 error:(NSError *)error
{
	if (error != nil) {
		NSLog(@"Sign in failed");
		[tabBarController dismissModalViewControllerAnimated:YES];
	}
	else {
		NSLog(@"Sign in successful");
		[self _assembleRequestManagerWithAuthentication:auth];
		[self _obtainUserId];
				
		[tabBarController dismissModalViewControllerAnimated:YES];
	}
}

#pragma mark AKRequestDelegate

- (void)request:(AKRequest*)request didFinishWithData:(NSData *)data
{
	NSString *responseString = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
	id responseInfo = [responseString JSONValue];
	NSString *userId = [responseInfo dbUserId];
	if ([userId length] > 0) {
		GDataOAuthKeychain *defaultKeychain = [GDataOAuthKeychain defaultKeychain];
		[defaultKeychain removePasswordForService:kAKAppName account:kAKUserIdKeychainKey error:NULL];
		[defaultKeychain setPassword:userId forService:kAKAppName account:kAKUserIdKeychainKey error:NULL];
		AK_RELEASE(_userId);
		_userId = [userId copy];
		[miniblogViewController reload];
	}
}

- (void)request:(AKRequest*)reqeust didFailWithError:(NSError*)error
{
	NSLog(@"request failed:%@", error);
}

#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}

- (void)dealloc
{
	AK_RELEASE(miniblogViewController);
	AK_RELEASE(mediaViewController);
	AK_RELEASE(tabBarController);
	AK_RELEASE(window);
	AK_RELEASE(_requestManager);
	AK_RELEASE(_userId);
	[super dealloc];
}

@end

